package com.github.hgbit.config;

import com.github.hgbit.filter.HttpServletRequestReplacedFilter;
import com.github.hgbit.filter.TraceLoggingFilter;
import com.github.hgbit.filter.XssAntiFilter;
import com.github.hgbit.properties.FilterOrderProperties;
import com.github.hgbit.properties.TraceLogProperties;
import com.github.hgbit.properties.XssProperties;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;

/**
 * FilterAutoConfig.
 *
 * @author huangguan
 * @since 2019-03-13
 */
@Configuration
@EnableConfigurationProperties({TraceLogProperties.class, FilterOrderProperties.class, XssProperties.class})
public class FilterAutoConfig {

    private Integer order;

    @Autowired
    private TraceLogProperties traceLogProperties;

    /**
     * 设置fiter加载起始优先级.
     *
     * @param filterOrderProperties filterOrderProperties
     */
    @Autowired
    public void setOrder(FilterOrderProperties filterOrderProperties) {
        if (null == filterOrderProperties.getOrderFrom()) {
            this.order = Ordered.HIGHEST_PRECEDENCE + 6;
        } else {
            this.order = Ordered.HIGHEST_PRECEDENCE + filterOrderProperties.getOrderFrom();
        }
    }

    /**
     * 可读httprequest filter.
     *
     * @return {@link FilterRegistrationBean}
     */
    @Bean
    public FilterRegistrationBean<HttpServletRequestReplacedFilter>
        httpServletRequestReplacedFilterFilterRegistrationBean() {
        FilterRegistrationBean<HttpServletRequestReplacedFilter> filterRegBean = new FilterRegistrationBean<>();
        filterRegBean.setFilter(new HttpServletRequestReplacedFilter());
        filterRegBean.addUrlPatterns("/*");
        filterRegBean.setOrder(order + 2);
        return filterRegBean;
    }

    /**
     * trace日志filter.
     *
     * @return {@link FilterRegistrationBean}
     */
    @Bean
    public FilterRegistrationBean<TraceLoggingFilter> traceLoggingFilterFilterRegistrationBean() {
        TraceLoggingFilter traceLoggingFilter = new TraceLoggingFilter();
        traceLoggingFilter.setSuccessCode(null == traceLogProperties.getSuccessCode()
            ? 0 : traceLogProperties.getSuccessCode());
        traceLoggingFilter.setExludeUrls(traceLogProperties.getExludePaths());
        traceLoggingFilter.setParamNames(traceLogProperties.getParamNames());
        FilterRegistrationBean<TraceLoggingFilter> filterRegBean = new FilterRegistrationBean<>();
        filterRegBean.setFilter(traceLoggingFilter);
        filterRegBean.addUrlPatterns("/*");
        filterRegBean.setOrder(order + 1);
        return filterRegBean;
    }

    /**
     * xss 防御 filter.
     *
     * @return {@link FilterRegistrationBean}
     */
    @Bean
    public FilterRegistrationBean<XssAntiFilter> xssAntiFilterFilterRegistrationBean(XssProperties xssProperties) {
        FilterRegistrationBean<XssAntiFilter> filterRegBean = new FilterRegistrationBean<>();
        filterRegBean.setFilter(new XssAntiFilter());
        if (StringUtils.isBlank(xssProperties.getUrlPatterns())) {
            filterRegBean.addUrlPatterns("/*");
        } else {
            filterRegBean.addUrlPatterns(xssProperties.getUrlPatterns());
        }
        filterRegBean.setOrder(order);
        return filterRegBean;
    }
}
